package com.emmy.walnut.view;

import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.service.autofill.Dataset;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;

import com.emmy.walnut.R;
import com.emmy.walnut.adapter.ItemDetailAdapter;
import com.emmy.walnut.model.Record;
import com.emmy.walnut.model.RecordSortHelperModel;
import com.emmy.walnut.presenter.StatisticsPresenter;
import com.emmy.walnut.presenter.iface.StatisticsPIface;
import com.emmy.walnut.util.ResourceUtil;
import com.emmy.walnut.util.TimeStampUtil;
import com.emmy.walnut.view.iface.StatisticsIface;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.formatter.PercentFormatter;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

public class StatisticsFragment extends Fragment implements StatisticsIface {

    private PieChart pieChart;

    private List<Record> records;

    //数据
    PieData pieData = new PieData();

    //字体
    protected Typeface tfRegular;
    protected Typeface tfLight;

    private RadioGroup radioGroup;
    private RadioButton day;
    private RadioButton week;
    private RadioButton month;
    private RadioButton year;
    private ImageButton back;
    private ImageButton forward;
    private TextView timePeriod;
    private RecyclerView recyclerView;
    private TextView noDataHintTextView;
    private ImageButton problemButton;

    private Spinner spinner;
    private ArrayAdapter spinnerAdapter;
    private ItemDetailAdapter itemDetailAdapter;

    private StatisticsPIface statisticsPIface;

    private long currentTimePeriod;
    private long startTimeStamp;
    private long endTimeStamp;

    private static final int DAY = 0;
    private static final int WEEK = 1;
    private static final int MONTH = 2;
    private static final int YEAR = 3;

    private static final String TAG = "StatisticsFragment";

    private SimpleDateFormat dayFormat = new SimpleDateFormat("MM月dd日,yyyy年");
    private SimpleDateFormat weekFormat = new SimpleDateFormat("MM月dd日");
    private SimpleDateFormat monthFormat = new SimpleDateFormat("MM月 yyyy年");
    private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy年");
    private DecimalFormat decimalFormat = new DecimalFormat("##0.0");

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_statistics, container, false);
        initView(view);
        return view;
    }

    private void initView(View view){

        statisticsPIface = new StatisticsPresenter(this);
        currentTimePeriod = System.currentTimeMillis();

        // 设置饼图格式
        pieChart = view.findViewById(R.id.pieChart);

        initChart();

        radioGroup = view.findViewById(R.id.radioGroup);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                updateTimePeriod();
            }
        });

        back = view.findViewById(R.id.backPeriod);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (radioGroup.getCheckedRadioButtonId()){
                    case R.id.day:
                        currentTimePeriod -= 86400000;
                        break;
                    case R.id.week:
                        currentTimePeriod -= 604800000;
                        break;
                    case R.id.month:
                        currentTimePeriod = TimeStampUtil.getMonthStartTime(currentTimePeriod)-1;
                        break;
                    case R.id.year:
                        currentTimePeriod = TimeStampUtil.getYearStartTime(currentTimePeriod)-1;
                        break;
                }
                updateTimePeriod();
            }
        });

        forward = view.findViewById(R.id.forwardPeriod);
        forward.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (radioGroup.getCheckedRadioButtonId()){
                    case R.id.day:
                        currentTimePeriod += 86400000;
                        break;
                    case R.id.week:
                        currentTimePeriod += 604800000;
                        break;
                    case R.id.month:
                        currentTimePeriod = TimeStampUtil.getMonthEndTime(currentTimePeriod)+1;
                        break;
                    case R.id.year:
                        currentTimePeriod = TimeStampUtil.getYearEndTime(currentTimePeriod)+1;
                        break;
                }
                updateTimePeriod();
            }
        });

        problemButton = view.findViewById(R.id.problem_image_button);
        problemButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View popupWindowView = LayoutInflater.from(getContext()).inflate(R.layout.popup_hint_layout,
                        null);
                TextView hintTextView = popupWindowView.findViewById(R.id.hint);
                PopupWindow popupWindow = new PopupWindow(popupWindowView,
                        ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
                        false);
                popupWindow.setOutsideTouchable(true);
                if (spinner.getSelectedItemPosition()==0){
                    hintTextView.setText("当数据满足以下条件之一将被归于其他类：\n\t类别占比不大于0.1%的数据\n\t类别占比排名不在前五");
                    popupWindow.showAsDropDown(problemButton);
                }else{
                }
            }
        });

        recyclerView = view.findViewById(R.id.recyclerView);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(linearLayoutManager);

        noDataHintTextView = view.findViewById(R.id.noDataHint);

        spinner = view.findViewById(R.id.spinner);
        spinnerAdapter = ArrayAdapter.createFromResource(getContext(),
                R.array.spinner_in_statistics, R.layout.item_spinner_layout);
        spinner.setAdapter(spinnerAdapter);

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                updateData(records);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        timePeriod = view.findViewById(R.id.timePeriod);
        day = view.findViewById(R.id.day);
        week = view.findViewById(R.id.week);
        month = view.findViewById(R.id.month);
        year = view.findViewById(R.id.year);
        day.setChecked(true);
        updateTimePeriod();
    }

    private void updateTimePeriod(){
        switch (radioGroup.getCheckedRadioButtonId()){
            case R.id.day:
                startTimeStamp = TimeStampUtil.getDailyStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getDailyEndTime(currentTimePeriod);
                timePeriod.setText(dayFormat.format(new Date(currentTimePeriod)));
                break;
            case R.id.week:
                startTimeStamp = TimeStampUtil.getWeekStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getWeekEndTime(currentTimePeriod);
                timePeriod.setText(String.format("%s-%s", weekFormat.format(new Date(TimeStampUtil.getWeekStartTime(currentTimePeriod))),
                        weekFormat.format(new Date(TimeStampUtil.getWeekEndTime(currentTimePeriod)))));
                break;
            case R.id.month:
                startTimeStamp = TimeStampUtil.getMonthStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getMonthEndTime(currentTimePeriod);
                timePeriod.setText(monthFormat.format(new Date(currentTimePeriod)));
                break;
            case R.id.year:
                startTimeStamp = TimeStampUtil.getYearStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getYearEndTime(currentTimePeriod);
                timePeriod.setText(yearFormat.format(new Date(currentTimePeriod)));
                break;
        }
        statisticsPIface.queryRecordWithPeriod(startTimeStamp, endTimeStamp);
    }

    @Override
    public void updateData(List<Record> data) {
        records = data;
        if (spinner.getSelectedItemPosition()==0){
            recyclerView.setVisibility(View.GONE);
            pieChart.setVisibility(View.VISIBLE);
            updateChart(data);
        }else{
            recyclerView.setVisibility(View.VISIBLE);
            pieChart.setVisibility(View.GONE);
            updateList(data);
        }
    }

    private void updateChart(List<Record> records){
        if (records==null||records.size()==0){
            pieChart.clear();
            noDataHintTextView.setVisibility(View.VISIBLE);
            return;
        }
        noDataHintTextView.setVisibility(View.GONE);
        List<RecordSortHelperModel> data = categoryRecord(records);
        List<PieEntry> pieEntries = new ArrayList<>();
        List<Integer> colors = new ArrayList<>();
        //表示剩余的百分比
        float leftover = 1;
        int i = 1;
        float temp;
        for (RecordSortHelperModel recordSortHelperModel : data){
            if (i>5){
                break;
            }else {
                temp = (float) recordSortHelperModel.getTimestamp() /
                        (float) RecordSortHelperModel.getTotalTimestamp();
                //如果过小我们则不显示
                if (temp<0.001){
                    continue;
                }
                //剩余百分比
                leftover -= temp;
                pieEntries.add(new PieEntry(temp, recordSortHelperModel.getName() +
                        "：" + decimalFormat.format(temp*100) + "%"));
                colors.add(getContext().getColor(ResourceUtil.getColorId("standard_color_"+i)));
            }
            i++;
        }
        //只展示五种类别数据，其余的归入其他类
        if (leftover!=0){
            pieEntries.add(new PieEntry(leftover, "其他" +
                    "：" + decimalFormat.format(leftover*100) + "%"));
            colors.add(getContext().getColor(ResourceUtil.getColorId("standard_color_6")));
        }
        PieDataSet pieDataSet = initDataset(pieEntries, colors);
        //设置数据集
        pieData.setDataSet(pieDataSet);
        pieData.setValueFormatter(new PercentFormatter(pieChart));
        pieData.setValueTextSize(11f);
        pieData.setValueTextColor(Color.WHITE);
        pieData.setValueTypeface(tfLight);
        pieChart.setData(pieData);
        //设置进入动画
        pieChart.animateY(1000, Easing.EaseInOutQuad);
        //刷新数据
        pieChart.invalidate();
    }

    private void updateList(List<Record> records){
        itemDetailAdapter = new ItemDetailAdapter(getContext(), records);
        recyclerView.setAdapter(itemDetailAdapter);
        if (records==null||records.size()==0){
            noDataHintTextView.setVisibility(View.VISIBLE);
            return;
        }
        noDataHintTextView.setVisibility(View.GONE);
    }

    private void initChart(){
        pieChart.setNoDataText("");
        pieChart.setDescription(null);
        //不在图上显示数字
        pieChart.setDrawEntryLabels(false);
        //设置偏移
        pieChart.setExtraOffsets(20, 20, 20, 20);
        pieChart.setDrawHoleEnabled(true);
        //设置内环颜色
        pieChart.setHoleColor(Color.WHITE);
        //设置内环半径的占比
        pieChart.setHoleRadius(0.8f);
        //设置旋转的摩擦系数
        pieChart.setDragDecelerationFrictionCoef(0.95f);
        //设置内环的半径
        pieChart.setHoleRadius(65f);
        //设置透明层的半径
        pieChart.setTransparentCircleRadius(66f);
        pieChart.setDrawCenterText(true);
        pieChart.setHighlightPerTapEnabled(true);

        // entry label styling
        pieChart.setEntryLabelColor(Color.WHITE);
        pieChart.setEntryLabelTextSize(12f);

        Legend legend = pieChart.getLegend();
        //设置图例的gravity
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        //设置图例的方向
        legend.setOrientation(Legend.LegendOrientation.VERTICAL);
        legend.setDrawInside(false);
        //设置图例Space
        legend.setXEntrySpace(7f);
        legend.setYEntrySpace(0f);
        //设置图例偏移
        legend.setXOffset(20f);
        legend.setYOffset(10f);
    }

    private PieDataSet initDataset(List<PieEntry> pieEntries, List<Integer> colors){
        PieDataSet pieDataSet = new PieDataSet(pieEntries, "");
        pieDataSet.setColors(colors);
        pieDataSet.setDrawValues(false);
        return pieDataSet;
    }

    /**
     *
     * 对查找出来的Record进行分类
     * @param records 查找出来的Record记录
     * @return  可以直接设置给饼图的数据
     */
    private List<RecordSortHelperModel> categoryRecord(List<Record> records){
        TreeMap<String, Long> category = new TreeMap<>();
        List<RecordSortHelperModel> recordSortHelperModels = new ArrayList<>();
        long sumTimestamp = 0;
        long tempTimestamp;
        for (Record record: records) {
            tempTimestamp = (Math.min(record.getEndTimestamp(), endTimeStamp)
                    - record.getStartTimestamp());
            if (!category.containsKey(record.getLabelName())) {
                category.put(record.getLabelName(), tempTimestamp);
            } else {
                category.put(record.getLabelName(), tempTimestamp + category.get(record.getLabelName()));
            }
            sumTimestamp += tempTimestamp;
        }

        for(String key:category.keySet()){
            recordSortHelperModels.add(new RecordSortHelperModel(key, category.get(key)));
        }
        RecordSortHelperModel.setTotalTimestamp(sumTimestamp);

        recordSortHelperModels.sort(new Comparator<RecordSortHelperModel>() {
            @Override
            public int compare(RecordSortHelperModel o1, RecordSortHelperModel o2) {
                return (int)(o1.getTimestamp()-o2.getTimestamp());
            }
        });

        return recordSortHelperModels;
    }
}
